package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.TaskTypeEnum;
import com.xbongbong.paas.help.FormDataValidateProductHelp;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.saas.domain.entity.ContractProductEntity;
import com.xbongbong.saas.domain.entity.OutstockProductEntity;
import com.xbongbong.saas.domain.entity.PurchaseBalanceEntity;
import com.xbongbong.saas.domain.entity.PurchaseProductEntity;
import com.xbongbong.saas.domain.entity.SmartReplenishmentEntity;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.PurchaseEntityExt;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.product.PurchaseProductEnum;
import com.xbongbong.saas.help.workflow.ContractHelp;
import com.xbongbong.saas.model.ContractProductModel;
import com.xbongbong.saas.model.OutstockProductModel;
import com.xbongbong.saas.model.PurchaseBalanceModel;
import com.xbongbong.saas.model.PurchaseProductModel;
import com.xbongbong.saas.model.SmartReplenishmentModel;
import com.xbongbong.saas.service.WaitPurchaseService;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author: wujian
 * @create: 2022-04-02 13:40
 * @description: 以销定购
 **/
@Service("WaitPurchaseService")
public class WaitPurchaseServiceImpl implements WaitPurchaseService {

    private static final Logger LOG = LoggerFactory.getLogger(WaitPurchaseServiceImpl.class);

    @Resource
    private SmartReplenishmentModel smartReplenishmentModel;
    @Resource
    private PurchaseBalanceModel purchaseBalanceModel;
    @Resource
    private OutstockProductModel outstockProductModel;
    @Resource
    private ContractProductModel contractProductModel;
    @Resource
    private FormDataValidateProductHelp formDataValidateProductHelp;
    @Resource
    private PurchaseProductModel purchaseProductModel;
    @Resource
    private ContractHelp contractHelp;
    /**
     * @Author: wujian
     * @Description: 新建销售出库单处理采购结存及智能补货数据
     * @Date: 下午4:13 2022/4/11
     * @Param: [corpid, addOutstockProductEntityList]
     * @return: void
     **/
    @Override
    public void formatContractOutstock(String corpid,List<OutstockProductEntity> addOutstockProductEntityList) throws XbbException{
        if (CollectionUtils.isNotEmpty(addOutstockProductEntityList)){
            Set<Long> contractIdSet = new HashSet<>();
            // 新建销售出库单采购结存表更新数据 计算建议采购量用
            List<String> onlyKeyList = new ArrayList<>();
            // 新建销售出库更新智能补货表中未出库数量
            List<Long> productIdList = new ArrayList<>();
            Map<Long,Double> smartMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<SmartReplenishmentEntity> needUpdateList = new ArrayList<>();
            Map<String,OutstockProductEntity> balanceMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<Long> contractProductIdList = new ArrayList<>();
            addOutstockProductEntityList.forEach(item ->{
                String onlyKey = item.getRefProductId() + "_" + item.getProductId();
                contractProductIdList.add(item.getRefProductId());
                contractIdSet.add(item.getRefId());
                // 销售出库可以有多个相同产品 需要封装一下数量
                if (!balanceMap.containsKey(onlyKey)){
                    onlyKeyList.add(onlyKey);
                }else {
                    item.setProductNum(Arith.add(balanceMap.get(onlyKey).getProductNum(),item.getProductNum()));
                }
                balanceMap.put(onlyKey,item);
                productIdList.add(item.getProductId());
                // 销售出库也可以有多条相同产品 智能补货需要更细总量
                if (smartMap.containsKey(item.getProductId())){
                    smartMap.put(item.getProductId(),Arith.add(smartMap.get(item.getProductId()),item.getProductNum()));
                }else {
                    smartMap.put(item.getProductId(),item.getProductNum());
                }
            });
            List<PurchaseBalanceEntity> purchaseBalanceEntityList = new ArrayList<>();
            if (CollectionsUtil.isNotEmpty(onlyKeyList)){
                purchaseBalanceEntityList = purchaseBalanceModel.findByOnlyKeys(corpid, onlyKeyList);
            }
            List<PurchaseBalanceEntity> updatePurchaseBalanceEntityList = new ArrayList<>();
            if (!balanceMap.isEmpty() && CollectionUtils.isNotEmpty(purchaseBalanceEntityList)){
                Map<String,PurchaseBalanceEntity> purchaseBalanceEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                purchaseBalanceEntityList.forEach(item -> purchaseBalanceEntityMap.put(item.getOnlyKey(),item));
                for (OutstockProductEntity outstockProductEntity : balanceMap.values()) {
                    Double productNum = outstockProductEntity.getProductNum();
                    PurchaseBalanceEntity purchaseBalanceEntity = purchaseBalanceEntityMap.get(outstockProductEntity.getRefProductId() + "_" +outstockProductEntity.getProductId());

                    if (Objects.nonNull(purchaseBalanceEntity)){
                        // 出库数量 > 采购结存数量 则结存更新为0 超发+=（出库数量-结存数量）
                        if (productNum >= purchaseBalanceEntity.getBalanceNum()){
                            purchaseBalanceEntity.setExceedStockNum(Arith.add(purchaseBalanceEntity.getExceedStockNum(),Arith.sub(productNum,purchaseBalanceEntity.getBalanceNum())));
                            purchaseBalanceEntity.setBalanceNum(0D);
                        }else {
                            // 出库数量 < 采购结存数量 则结存更新为 结存-出库
                            purchaseBalanceEntity.setBalanceNum(Arith.sub(purchaseBalanceEntity.getBalanceNum(),productNum));
                        }
                        //防止空指针
                        purchaseBalanceEntity.setUpdateTime(DateTimeUtil.getInt());
                        updatePurchaseBalanceEntityList.add(purchaseBalanceEntity);
                    }
                }
                if (CollectionsUtil.isNotEmpty(updatePurchaseBalanceEntityList)){
                    purchaseBalanceModel.updateBatch(purchaseBalanceEntityList,corpid);
                }
            }

            // 查询出销售出库单中所有产品在智能补货表中的数据
            List<SmartReplenishmentEntity> smartReplenishmentEntitys = new ArrayList<>();
            if (CollectionsUtil.isNotEmpty(productIdList)){
                smartReplenishmentEntitys = smartReplenishmentModel.getByProductList(corpid,productIdList);
            }
            if (CollectionsUtil.isNotEmpty(smartReplenishmentEntitys)){
                for (SmartReplenishmentEntity smartReplenishmentEntity : smartReplenishmentEntitys) {
                    Long productId = smartReplenishmentEntity.getProductId();
                    if (smartMap.containsKey(productId)){
                        smartReplenishmentEntity.setWaitOutstockNum(Arith.sub(smartReplenishmentEntity.getWaitOutstockNum(),smartMap.get(productId)));
                        needUpdateList.add(smartReplenishmentEntity);
                    }

                }
            }
            if (CollectionsUtil.isNotEmpty(needUpdateList)){
                try {
                    smartReplenishmentModel.updateBatch(needUpdateList,corpid);
                }catch (Exception e){
                    LOG.error("WaitPurchaseServiceImpl.formatPurchaseBalanceData() 插入智能补货数据时出错", e);
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                }
            }
            if (CollectionsUtil.isNotEmpty(contractProductIdList)){
                List<ContractProductEntity> contractProductEntityList = contractProductModel.getById(contractProductIdList, corpid);
                if (CollectionsUtil.isNotEmpty(contractProductEntityList)){
                    contractHelp.handleWaitPurchaseNum(corpid,contractProductEntityList,contractIdSet);
                    try {
                        contractProductModel.updateBatch(contractProductEntityList,corpid);
                    }catch (Exception e){
                        LOG.error("WaitPurchaseServiceImpl.formatPurchaseBalanceData() 更新合同产品表中缺货数量出错", e);
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                    }

                }
            }
        }
    }
//    @Override
    public void formatContractOutstockData(SaasFormSaveDTO saasFormSaveDTO,Long outstockId) throws XbbException {
        JSONObject data = saasFormSaveDTO.getNewData();
        String corpid = saasFormSaveDTO.getCorpid();
        ContractEntityExt contractEntityExt = null;
        Long refId = Objects.isNull(data.getLong(OutstockEnum.REF_ID.getAttr())) ? 0L : data.getLong(OutstockEnum.REF_ID.getAttr());

        List<OutstockProductEntity> addOutstockProductEntityList = outstockProductModel.getProductsByOutstockIdAndType(corpid, Collections.singletonList(outstockId), OutstockTypeEnum.CONTRACT_OUTSTOCK.getCode());
        if (CollectionUtils.isNotEmpty(addOutstockProductEntityList)){
            // 新建销售出库单采购结存表更新数据 计算建议采购量用
            List<String> onlyKeyList = new ArrayList<>();
            // 新建销售出库更新智能补货表中未出库数量
            List<Long> productIdList = new ArrayList<>();
            Map<Long,Double> smartMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<SmartReplenishmentEntity> needUpdateList = new ArrayList<>();
            Map<String,OutstockProductEntity> balanceMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            addOutstockProductEntityList.forEach(item ->{
                String onlyKey = item.getRefProductId() + "_" + item.getProductId();
                // 销售出库可以有多个相同产品 需要封装一下数量
                if (!balanceMap.containsKey(onlyKey)){
                    onlyKeyList.add(onlyKey);
                }else {
                    item.setProductNum(Arith.add(balanceMap.get(onlyKey).getProductNum(),item.getProductNum()));
                }
                balanceMap.put(onlyKey,item);
                productIdList.add(item.getProductId());
                // 销售出库也可以有多条相同产品 智能补货需要更细总量
                if (smartMap.containsKey(item.getProductId())){
                    smartMap.put(item.getProductId(),Arith.add(smartMap.get(item.getProductId()),item.getProductNum()));
                }else {
                    smartMap.put(item.getProductId(),item.getProductNum());
                }
            });
            List<PurchaseBalanceEntity> purchaseBalanceEntityList = new ArrayList<>();
            if (CollectionsUtil.isNotEmpty(onlyKeyList)){
                purchaseBalanceEntityList = purchaseBalanceModel.findByOnlyKeys(corpid, onlyKeyList);
            }
            List<PurchaseBalanceEntity> updatePurchaseBalanceEntityList = new ArrayList<>();
            if (!balanceMap.isEmpty() && CollectionUtils.isNotEmpty(purchaseBalanceEntityList)){
                Map<String,PurchaseBalanceEntity> purchaseBalanceEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                purchaseBalanceEntityList.forEach(item -> purchaseBalanceEntityMap.put(item.getOnlyKey(),item));
                for (OutstockProductEntity outstockProductEntity : balanceMap.values()) {
                    Double productNum = outstockProductEntity.getProductNum();
                    PurchaseBalanceEntity purchaseBalanceEntity = purchaseBalanceEntityMap.get(outstockProductEntity.getRefProductId() + "_" +outstockProductEntity.getProductId());

                    if (Objects.nonNull(purchaseBalanceEntity)){
                        // 出库数量 > 采购结存数量 则结存更新为0 超发+=（出库数量-结存数量）
                        if (productNum >= purchaseBalanceEntity.getBalanceNum()){
                            purchaseBalanceEntity.setExceedStockNum(Arith.add(purchaseBalanceEntity.getExceedStockNum(),Arith.sub(productNum,purchaseBalanceEntity.getBalanceNum())));
                            purchaseBalanceEntity.setBalanceNum(0D);
                        }else {
                            // 出库数量 < 采购结存数量 则结存更新为 结存-出库
                            purchaseBalanceEntity.setBalanceNum(Arith.sub(purchaseBalanceEntity.getBalanceNum(),productNum));
                        }
                        //防止空指针
                        purchaseBalanceEntity.setUpdateTime(DateTimeUtil.getInt());
                        updatePurchaseBalanceEntityList.add(purchaseBalanceEntity);
                    }
                }
                if (CollectionsUtil.isNotEmpty(updatePurchaseBalanceEntityList)){
                    purchaseBalanceModel.updateBatch(purchaseBalanceEntityList,corpid);
                }
            }

            // 查询出销售出库单中所有产品在智能补货表中的数据
            List<SmartReplenishmentEntity> smartReplenishmentEntitys = new ArrayList<>();
            if (CollectionsUtil.isNotEmpty(productIdList)){
                smartReplenishmentEntitys = smartReplenishmentModel.getByProductList(corpid,productIdList);
            }
            if (CollectionsUtil.isNotEmpty(smartReplenishmentEntitys)){
                for (SmartReplenishmentEntity smartReplenishmentEntity : smartReplenishmentEntitys) {
                    Long productId = smartReplenishmentEntity.getProductId();
                    if (smartMap.containsKey(productId)){
                        smartReplenishmentEntity.setWaitOutstockNum(Arith.sub(smartReplenishmentEntity.getWaitOutstockNum(),smartMap.get(productId)));
                        needUpdateList.add(smartReplenishmentEntity);
                    }

                }
            }
            if (CollectionsUtil.isNotEmpty(needUpdateList)){
                try {
                    smartReplenishmentModel.updateBatch(needUpdateList,corpid);
                }catch (Exception e){
                    LOG.error("WaitPurchaseServiceImpl.formatPurchaseBalanceData() 插入智能补货数据时出错", e);
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                }
            }
        }
    }

//    @Override
    public void purchaseAfterSave(PurchaseEntityExt purchaseEntityExt, boolean isNew) throws XbbException {
        // 采购合同关联产品特殊处理
        JSONObject data = purchaseEntityExt.getData();
        Long purchaseId = purchaseEntityExt.getId();
        String corpid = purchaseEntityExt.getCorpid();


        Map<Long, PurchaseProductEntity> originProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 智能补货编辑前后的总量Map
        Map<Long,Double> changeBeforeNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long,Double> changeAfterNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 以销定购编辑前后的总量map
        Map<String ,Double> balanceBeforeNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String ,Double> balanceAfterNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<String> onlyKeyList = new ArrayList<>();
        // 本次采购合同动到的所有产品ID
        List<Long> allProductIdList = new ArrayList<>();
        Map<Long, PurchaseProductEntity> approveFailedProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (!isNew){
            //非新建情况下，取得采购合同编辑前的关联产品
            List<PurchaseProductEntity> purchaseProductList = purchaseProductModel.getProductsByPurchaseId(corpid,purchaseId, Arrays.asList(DelEnum.NORMAL.getDel(), DelEnum.APPROVE_FAILED.getDel()));
            for (PurchaseProductEntity purchaseProduct : purchaseProductList) {
                Long productId = purchaseProduct.getProductId();
                if (Objects.equals(DelEnum.NORMAL.getDel(), purchaseProduct.getDel())) {
                    originProductMap.put(purchaseProduct.getId(), purchaseProduct);
                    if(changeBeforeNumMap.containsKey(purchaseProduct.getProductId())){
                        changeBeforeNumMap.put(productId,Arith.add(changeBeforeNumMap.get(productId),purchaseProduct.getProductNum()));
                    }else {
                        changeBeforeNumMap.put(productId,purchaseProduct.getProductNum());
                    }
                    allProductIdList.add(productId);
                } else {
                    approveFailedProductMap.put(purchaseProduct.getId(), purchaseProduct);
                }
                Long contractId = purchaseProduct.getContractId();
                Long contractProductId = purchaseProduct.getContractProductId();
                if (Objects.nonNull(contractProductId)){
                    String onlyKey = contractProductId + "_" + productId;
                    if (balanceBeforeNumMap.containsKey(onlyKey)){
                        balanceBeforeNumMap.put(onlyKey,Arith.add(balanceBeforeNumMap.get(onlyKey),purchaseProduct.getProductNum()));
                    }else {
                        onlyKeyList.add(onlyKey);
                        balanceBeforeNumMap.put(onlyKey,purchaseProduct.getProductNum());
                    }
                }
            }
        }
        //新增产品
        List<PurchaseProductEntity> productAddList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        //编辑产品
        List<PurchaseProductEntity> productUpdateList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 采购产品数据
        JSONArray productListArray = data.getJSONArray(PurchaseEnum.PRODUCT.getAttr());
        Map<Long, PaasFormDataEntityExt> productMap = formDataValidateProductHelp.product2saveMap(corpid,productListArray);

        for (int i = 0; i < productListArray.size(); i++) {
            JSONObject jsonObject = productListArray.getJSONObject(i);
            Long pageProductId = jsonObject.getLong(SelectProductEnum.PRODUCT.getAttr());
            allProductIdList.add(pageProductId);
            Long businessProductId = jsonObject.getLong(BusinessConstant.PRODUCT_SUB_ID);
            Double productNum = jsonObject.getDouble(PurchaseProductEnum.NUM.getAttr());
            Double price = jsonObject.getDouble(PurchaseProductEnum.PURCHASE_PRICE.getAttr());
            price = price != null ? price : 0;
            if (changeAfterNumMap.containsKey(pageProductId)) {
                changeAfterNumMap.put(pageProductId, Arith.add(changeAfterNumMap.get(pageProductId), productNum));
            } else {
                changeAfterNumMap.put(pageProductId, productNum);
            }
            boolean addProductFlag = formDataValidateProductHelp.addProductFlag(businessProductId);
            PurchaseProductEntity purchaseProduct;
            if (addProductFlag) {
                //新增产品
                purchaseProduct = new PurchaseProductEntity();
                purchaseProduct.setInstockNum(0D);
                productAddList.add(purchaseProduct);
            } else if (originProductMap.containsKey(businessProductId)) {
                //编辑产品
                purchaseProduct = originProductMap.get(businessProductId);
                productUpdateList.add(purchaseProduct);
                //只剩删除的产品
                originProductMap.remove(businessProductId);
            } else if (approveFailedProductMap.containsKey(businessProductId)) {
                //编辑产品
                purchaseProduct = approveFailedProductMap.get(businessProductId);
                productUpdateList.add(purchaseProduct);
                // 将审批拒绝，撤回的数据，置回正常
                purchaseProduct.setDel(DelEnum.NORMAL.getDel());
            } else {
                //删除产品
                continue;
            }
            JSONObject productData = productMap.get(pageProductId).getData();
            Integer enableMultiUnit = productData.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr());
            if (Objects.equals(enableMultiUnit, 1)) {
                formDataValidateProductHelp.setBusinessUnit(jsonObject, purchaseProduct);
                purchaseProduct.setProductUnit(jsonObject.getString(SelectProductEnum.UNIT.getAttr()));
            } else {
                purchaseProduct.setProductUnit(productData.getString(ProductEnum.UNIT.getAttr()));
                jsonObject.put(PurchaseProductEnum.UNIT.getAttr(),productData.getString(ProductEnum.UNIT.getAttr()));
            }
            purchaseProduct.setCorpid(corpid);
            purchaseProduct.setPurchaseSheetId(purchaseId == null ? 0L : purchaseId);
            purchaseProduct.setParentId(productData.getLong(ProductEnum.PARENT_ID.getAttr()));
            purchaseProduct.setProductId(pageProductId);
            purchaseProduct.setProductNum(productNum);
            purchaseProduct.setProductPrice(price);
            purchaseProduct.setDiscount(100D);
            purchaseProduct.setDel(0);
            purchaseProduct.setProductName(productData.getString(ProductEnum.NAME.getAttr()));
            String productNo = productData.getString(ProductEnum.PRODUCT_NO.getAttr());
            productNo = Objects.isNull(productNo) ? "" : productNo;
            purchaseProduct.setProductNo(productNo);
            purchaseProduct.setProductSpecification(productData.getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr()));
            String unit = productData.getString(ProductEnum.UNIT.getAttr());
            unit = Objects.isNull(unit) ? "" : unit;

            purchaseProduct.setThumbnail(productData.getString(ProductEnum.THUMBNAIL.getAttr()));
            purchaseProduct.setOtherCharge(0D);
            purchaseProduct.setData(jsonObject);



            // 新建采购合同 将合同与产品关联起来
            String contractNo = jsonObject.getString(PurchaseProductEnum.CONTRACT_NO.getAttr());
            Object cid = jsonObject.get("contractId");
            Object cpid = jsonObject.get("contractProductId");
            if (Objects.nonNull(contractNo) && Objects.nonNull(cid) && Objects.nonNull(cpid)){
                Long contractId = Long.valueOf(cid.toString());
                purchaseProduct.setContractId(contractId);
                Long contractProductId = Long.valueOf(cpid.toString());
                purchaseProduct.setContractProductId(contractProductId);
                String onlykey = contractProductId + "_" + pageProductId;
                if (balanceAfterNumMap.containsKey(onlykey)){
                    balanceAfterNumMap.put(onlykey,Arith.add(balanceAfterNumMap.get(onlykey),productNum));
                }else {
                    balanceAfterNumMap.put(onlykey,productNum);
                    onlyKeyList.add(onlykey);
                }
            }
        }
        List<PurchaseBalanceEntity> purchaseBalanceEntityList = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(onlyKeyList)){
            purchaseBalanceEntityList = purchaseBalanceModel.findByOnlyKeys(corpid, onlyKeyList);
        }
        Map<String, PurchaseBalanceEntity> purchaseBalanceEntityMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (CollectionsUtil.isNotEmpty(purchaseBalanceEntityList)){
            purchaseBalanceEntityList.forEach(item -> purchaseBalanceEntityMap.put(item.getOnlyKey(),item));
        }
        // 封装此次变更的结存数据 key = productId   value = 此次变化量
        Map<String,Double> balanceChangeNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (String onlyKey : onlyKeyList) {
            Double afterNum = balanceAfterNumMap.getOrDefault(onlyKey, 0D);
            Double beforeNum = balanceBeforeNumMap.getOrDefault(onlyKey, 0D);
            balanceChangeNumMap.put(onlyKey,Arith.sub(afterNum,beforeNum));
        }
        // 新建编辑删除采购合同关联产品 处理结存表数据
        List<PurchaseBalanceEntity> updateBalanceList = new ArrayList<>();
        for (String onlyKey : onlyKeyList) {
            if (purchaseBalanceEntityMap.containsKey(onlyKey) && balanceChangeNumMap.containsKey(onlyKey)){
                Double changeNum = balanceChangeNumMap.get(onlyKey);
                PurchaseBalanceEntity purchaseBalanceEntity = purchaseBalanceEntityMap.get(onlyKey);
                Double exceedStockNum = purchaseBalanceEntity.getExceedStockNum();
                Double balanceNum = purchaseBalanceEntity.getBalanceNum();
                // 变化之后的数量大于之前的数量说明是新增了  结存数量增加
                if (changeNum >= 0){
                    purchaseBalanceEntity.setBalanceNum(Arith.add(balanceNum,changeNum));
                }else {
                    // 小于0时说明是有编辑或者删除的了 判断变化量是否大于结存 如果大于结余直接从结存中扣除 否则从超发中扣除
                    if (Math.abs(changeNum) <= balanceNum){
                        purchaseBalanceEntity.setBalanceNum(Arith.sub(balanceNum,Math.abs(changeNum)));
                    }else {
                        purchaseBalanceEntity.setBalanceNum(0D);
                        purchaseBalanceEntity.setExceedStockNum(Arith.add(exceedStockNum,Arith.sub(Math.abs(changeNum),balanceNum)));
                    }
                }
                updateBalanceList.add(purchaseBalanceEntity);
            }
        }
        try {
            if (CollectionsUtil.isNotEmpty(updateBalanceList)){
                purchaseBalanceModel.updateBatch(updateBalanceList,corpid);
            }
        }catch (Exception e){
            LOG.error("PurchaseServiceImpl.afterSave() 更新采购结存数据时出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        // 编辑采购合同 删除关联产品 更新智能补货待入库数量
        // 智能补货数据表中查询出所有关联到的产品
        List<SmartReplenishmentEntity> smartReplenishmentEntityList = smartReplenishmentModel.getByProductList(corpid,allProductIdList);
        // key = productId   value = 此次变化量
        Map<Long,Double> changeNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (Long productId : allProductIdList) {
            if(!changeNumMap.containsKey(productId)){
                Double afterNum = changeAfterNumMap.getOrDefault(productId, 0D);
                Double beforeNum = changeBeforeNumMap.getOrDefault(productId, 0D);
                // 最后只剩下删除的产品数据
                changeNumMap.put(productId,Arith.sub(afterNum,beforeNum));
            }
        }
        if (CollectionsUtil.isNotEmpty(smartReplenishmentEntityList)){
            for (SmartReplenishmentEntity smartReplenishmentEntity : smartReplenishmentEntityList) {
                Long productId = smartReplenishmentEntity.getProductId();
                if (changeNumMap.containsKey(productId)){
                    Double pendingInstockNum = Objects.isNull(smartReplenishmentEntity.getPendingInstockNum()) ? 0D : smartReplenishmentEntity.getPendingInstockNum();
                    smartReplenishmentEntity.setPendingInstockNum(Arith.add(pendingInstockNum,changeNumMap.get(productId)) >= 0D ? Arith.add(pendingInstockNum,changeNumMap.get(productId)) : 0D);
                }
            }
            try {
                smartReplenishmentModel.updateBatch(smartReplenishmentEntityList, corpid);
            }catch (Exception e){
                LOG.error("PurchaseService.afterSave() 更新智能补货数据时出错", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
        }
    }


    /**
     * @Author: wujian
     * @Description: 新建编辑合同产品处理采购结存及智能补货数据
     * @Date: 下午6:29 2022/4/6
     * @Param: [insertList, updateList, delList]
     * @param: changeBeforeNumMap:编辑前数据库中的数量
     * @return: void
     **/
    @Override
    public void formatContract(List<ContractProductEntity> insertList, List<ContractProductEntity> updateList, List<ContractProductEntity> delList,Map<Long,Double> changeBeforeNumMap,String corpid,Integer taskType) throws XbbException {
        if(Objects.equals(TaskTypeEnum.AGAIN_COMMIT.getType(),taskType)){
            // 如果是重新提交的话 就不存在差值的情况 所以变化前的数量都是0
            changeBeforeNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        }
        if (CollectionUtils.isNotEmpty(insertList)){
            List<PurchaseBalanceEntity> purchaseBalanceEntityList = new ArrayList<>();
            // 智能补货需要插入的数量map
            Map<Long,Double> smartMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<Long> smartProductIdList = new ArrayList<>();
            // 如果是新建 则直接把数据苦中的合同产品直接插入采购结存
            for (ContractProductEntity contractProductEntity : insertList) {
                Long contractProductEntityId = contractProductEntity.getId();
                Long productId = contractProductEntity.getProductId();
                Long contractId = contractProductEntity.getContractId();
                smartProductIdList.add(productId);
                Double productNum = contractProductEntity.getProductNum();
                PurchaseBalanceEntity purchaseBalanceEntity = new PurchaseBalanceEntity();
                purchaseBalanceEntity.setCorpid(corpid);
                purchaseBalanceEntity.setContractId(contractId);
                purchaseBalanceEntity.setProductId(productId);
                purchaseBalanceEntity.setParentProductId(contractProductEntity.getParentId());
                purchaseBalanceEntity.setContractProductId(contractProductEntityId);
                purchaseBalanceEntity.setBalanceNum(0D);
                purchaseBalanceEntity.setExceedStockNum(0D);
                purchaseBalanceEntity.setOnlyKey(contractProductEntityId + "_" + productId);
                purchaseBalanceEntity.setDel(0);
                purchaseBalanceEntity.setAddTime(DateTimeUtil.getInt());
                purchaseBalanceEntity.setUpdateTime(DateTimeUtil.getInt());
                purchaseBalanceEntityList.add(purchaseBalanceEntity);
                if (smartMap.containsKey(productId)){
                    smartMap.put(productId,Arith.add(smartMap.get(productId),productNum));
                }else {
                    smartMap.put(productId,productNum);
                }
            }
            try {
                purchaseBalanceModel.insertBatch(purchaseBalanceEntityList);
            }catch (Exception e){
                LOG.error("ContractServiceImpl.afterSave() 插入采购结存数据时出错", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }

            // 查询出已有的智能补货数据
            // 查询出变化了的所有智能补货产品数据
            List<SmartReplenishmentEntity> smartReplenishmentEntities = smartReplenishmentModel.getByProductList(corpid, smartProductIdList);
            for (SmartReplenishmentEntity smartReplenishmentEntity : smartReplenishmentEntities) {
                Long productId = smartReplenishmentEntity.getProductId();
                Double contractNum = smartMap.getOrDefault(productId,0D);
                smartReplenishmentEntity.setWaitOutstockNum(Arith.add(smartReplenishmentEntity.getWaitOutstockNum(),contractNum));
            }

            try {
                smartReplenishmentModel.updateBatch(smartReplenishmentEntities, corpid);
            }catch (Exception e){
                LOG.error("ContractServiceImpl.afterSave() 插入智能补货数据时出错", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
        }

        // 编辑了的产品（编辑了的产品采购结存数量不用管 只用更新智能补货数据）
        if (CollectionUtils.isNotEmpty(updateList)){
            List<Long> updateProductIdList = new ArrayList<>();
            // key = productId  value=改变了的数量
            Map<Long,Double> changeNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (ContractProductEntity contractProductEntity : updateList) {
                Long contractProductEntityId = contractProductEntity.getId();
                Long productId = contractProductEntity.getProductId();
                updateProductIdList.add(productId);
                Double productNum = contractProductEntity.getProductNum();
                // 改变之前的数量
                Double changeBeforeNum = changeBeforeNumMap.getOrDefault(contractProductEntityId, 0D);
                // 改变量 = 改变之后的 - 改变之前的
                Double changeNum = Arith.sub(productNum,changeBeforeNum);
                if (changeBeforeNumMap.containsKey(productId)){
                    changeBeforeNumMap.put(productId,Arith.add(changeBeforeNumMap.getOrDefault(productId,0D),changeNum));
                }else {
                    changeBeforeNumMap.put(productId,changeNum);
                }
            }
            // 查询需要更新的智能补货的数据
            // 查询出已有的智能补货数据
            // 查询出变化了的所有智能补货产品数据
            List<SmartReplenishmentEntity> smartReplenishmentEntities = smartReplenishmentModel.getByProductList(corpid, updateProductIdList);
            for (SmartReplenishmentEntity smartReplenishmentEntity : smartReplenishmentEntities) {
                Long productId = smartReplenishmentEntity.getProductId();
                Double changeNum = changeBeforeNumMap.getOrDefault(productId, 0D);
                smartReplenishmentEntity.setWaitOutstockNum(Arith.add(smartReplenishmentEntity.getWaitOutstockNum(),changeNum));
            }
            try {
                smartReplenishmentModel.updateBatch(smartReplenishmentEntities, corpid);
            }catch (Exception e){
                LOG.error("ContractServiceImpl.afterSave() 插入智能补货数据时出错", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
        }

        // 删除了的产品
        if (CollectionUtils.isNotEmpty(delList)){
            List<Long> delProductIdList = new ArrayList<>();
            List<String> onlyKeyList = new ArrayList<>();
            Map<String,Double> onlyKeyNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<Long,Double> delNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (ContractProductEntity contractProductEntity : delList) {
                Long productId = contractProductEntity.getProductId();
                delProductIdList.add(productId);
                Long contractProductId = contractProductEntity.getId();
                Long contractId = contractProductEntity.getContractId();
                String onlyKey = contractProductId + "_" + productId;
                onlyKeyList.add(onlyKey);
                Double productNum = contractProductEntity.getProductNum();
                if (delNumMap.containsKey(productId)){
                    delNumMap.put(productId,Arith.add(delNumMap.get(productId),productNum));
                }else {
                    delNumMap.put(productId,productNum);
                }
                if (!onlyKeyNumMap.containsKey(onlyKey)){
                    onlyKeyNumMap.put(onlyKey,productNum);
                }else {
                    onlyKeyNumMap.put(onlyKey,Arith.add(onlyKeyNumMap.get(onlyKey),productNum));
                }
            }
            // 查询所有采购结存的数据将del置为1
            if (CollectionUtils.isNotEmpty(onlyKeyList)){
                purchaseBalanceModel.batchUpdateDel(corpid,onlyKeyList,DelEnum.DELETE.getDel());
            }

            // 查询要删除的所有智能补货数据
            if (CollectionUtils.isNotEmpty(delProductIdList)){
                List<SmartReplenishmentEntity> smartReplenishmentEntities = smartReplenishmentModel.getByProductList(corpid, delProductIdList);
                if (CollectionUtils.isNotEmpty(smartReplenishmentEntities)){
                    for (SmartReplenishmentEntity smartReplenishmentEntity : smartReplenishmentEntities) {
                        Long productId = smartReplenishmentEntity.getProductId();
                        Double changeNum = delNumMap.getOrDefault(productId, 0D);
                        smartReplenishmentEntity.setWaitOutstockNum(Arith.sub(smartReplenishmentEntity.getWaitOutstockNum(),changeNum));
                    }
                    try {
                        smartReplenishmentModel.updateBatch(smartReplenishmentEntities, corpid);
                    }catch (Exception e){
                        LOG.error("ContractServiceImpl.afterSave() 插入智能补货数据时出错", e);
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                    }
                }
            }

        }
    }

    /**
     * @Author: wujian
     * @Description: 采购合同关联产品保存后处理采购结存及智能补货数据
     * @Date: 下午5:39 2022/4/7
     * @Param: [productAddList, updateList, delList]
     * smartNumMap:智能补货变更数量
     * waitPurchaseNumMap 以销定购变更数量
     * isAgainCommit 是否重新提交
     * @return: void
     **/
    @Override
    public void formatPurchase(String corpid,List<PurchaseProductEntity> insertList, List<PurchaseProductEntity> updateList, List<PurchaseProductEntity> delList, Map<Long, Double> smartNumMap, Map<String, Double> waitPurchaseNumMap,boolean isAgainCommit) throws XbbException {
        if (CollectionUtils.isNotEmpty(insertList) || CollectionUtils.isNotEmpty(updateList) || CollectionUtils.isNotEmpty(delList)){
            List<String> onlyKeyList = new ArrayList<>();
            Set<Long> productIdSet = new HashSet<>();
            List<PurchaseBalanceEntity> updataBalanceList = new ArrayList<>();
            List<Long> contractProductIdList = new ArrayList<>();
            Set<Long> contractIdSet = new HashSet<>();
            if (CollectionUtils.isNotEmpty(updateList)){
                insertList.addAll(updateList);
            }
            // 重新提交的删除掉的产品不用计算
            if (CollectionUtils.isNotEmpty(delList) && !isAgainCommit){
                insertList.addAll(delList);
            }
            insertList.forEach(item ->{
                Long contractProductId = item.getContractProductId();
                Long contractId = item.getContractId();
                Long productId = item.getProductId();
                if (Objects.nonNull(contractProductId)){
                    contractProductIdList.add(contractProductId);
                    contractIdSet.add(contractId);
                    String onlyKey = contractProductId + "_" + productId;
                    onlyKeyList.add(onlyKey);
                }
                if (Objects.nonNull(productId)){
                    productIdSet.add(productId);
                }
            });
            // 查询除所有需要更新的采购结存数据
            List<PurchaseBalanceEntity> purchaseBalanceEntityList = new ArrayList<>();
            if (CollectionsUtil.isNotEmpty(onlyKeyList)){
                purchaseBalanceEntityList = purchaseBalanceModel.findByOnlyKeys(corpid, onlyKeyList);
                if (CollectionUtils.isNotEmpty(purchaseBalanceEntityList)){
                    for (PurchaseBalanceEntity purchaseBalanceEntity : purchaseBalanceEntityList) {
                        String onlyKey = purchaseBalanceEntity.getOnlyKey();
                        Double balanceNum = purchaseBalanceEntity.getBalanceNum();
                        Double exceedStockNum = purchaseBalanceEntity.getExceedStockNum();
                        Double changeNum = waitPurchaseNumMap.getOrDefault(onlyKey, 0D);
                        // 变化之后的数量大于之前的数量说明是新增了  结存数量增加
                        if (changeNum >= 0){
                            purchaseBalanceEntity.setBalanceNum(Arith.add(balanceNum,changeNum));
                        }else {
                            // 小于0时说明是有编辑或者删除的了 判断变化量是否大于结存 如果变化量小于结存则直接从结存中扣除 否则将结存置为0剩余的算做超发
                            if (Math.abs(changeNum) <= balanceNum){
                                purchaseBalanceEntity.setBalanceNum(Arith.sub(balanceNum,Math.abs(changeNum)));
                            }else {
                                purchaseBalanceEntity.setBalanceNum(0D);
                                purchaseBalanceEntity.setExceedStockNum(Arith.add(exceedStockNum,Arith.sub(Math.abs(changeNum),balanceNum)));
                            }
                        }
                    }
                    try {
                        if (CollectionsUtil.isNotEmpty(purchaseBalanceEntityList)){
                            purchaseBalanceModel.updateBatch(purchaseBalanceEntityList,corpid);
                        }
                    }catch (Exception e){
                        LOG.error("PurchaseServiceImpl.afterSave() 更新采购结存数据时出错", e);
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                    }
                }
            }
            // 更新智能补货数据
            List<SmartReplenishmentEntity> smartReplenishmentEntityList = smartReplenishmentModel.getByProductList(corpid, new ArrayList<>(productIdSet));
            if (CollectionUtils.isNotEmpty(smartReplenishmentEntityList)){
                for (SmartReplenishmentEntity smartReplenishmentEntity : smartReplenishmentEntityList) {
                    Long productId = smartReplenishmentEntity.getProductId();
                    Double changeNum = smartNumMap.getOrDefault(productId, 0D);
                    Double pendingInstockNum = Objects.isNull(smartReplenishmentEntity.getPendingInstockNum()) ? 0D : smartReplenishmentEntity.getPendingInstockNum();
                    smartReplenishmentEntity.setPendingInstockNum(Arith.add(pendingInstockNum,changeNum) >= 0D ? Arith.add(pendingInstockNum,changeNum) : 0D);
                }
                try {
                    smartReplenishmentModel.updateBatch(smartReplenishmentEntityList, corpid);
                }catch (Exception e){
                    LOG.error("PurchaseService.afterSave() 更新智能补货数据时出错", e);
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                }
            }
            // 处理合同产品表中缺货数量字段
            if(CollectionsUtil.isNotEmpty(contractProductIdList)){
                List<ContractProductEntity> contractProductEntityList = contractProductModel.getById(contractProductIdList, corpid);
                if (CollectionsUtil.isNotEmpty(contractProductEntityList)) {
                    contractHelp.handleWaitPurchaseNum(corpid, contractProductEntityList, contractIdSet);
                    try {
                        contractProductModel.updateBatch(contractProductEntityList, corpid);
                    } catch (Exception e) {
                        LOG.error("PurchaseService.afterSave() 更新合同产品表中缺货数量数据时出错", e);
                    }
                }
            }
        }
    }

    @Override
    public void deletePurchase(String corpid,List<PurchaseProductEntity> purchaseProductEntityList) throws XbbException {
        Map<Long,Double> smartMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> productIdList = new ArrayList<>();
        List<Long> contractProductIdList = new ArrayList<>();
        Set<Long> contractIdSet = new HashSet<>();
        Map<Long,Double> purchaseNumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (CollectionsUtil.isNotEmpty(purchaseProductEntityList)){
            List<String> onlyKeyList = new ArrayList<>();
            Map<String,Double> balanceMap = new HashMap<>();
            for (PurchaseProductEntity purchaseProductEntity : purchaseProductEntityList) {
                Long productId = purchaseProductEntity.getProductId();
                Long contractProductId = purchaseProductEntity.getContractProductId();
                Long contractId = purchaseProductEntity.getContractId();
                Double productNum = purchaseProductEntity.getProductNum();

                productIdList.add(productId);
                // 统计删除产品的总量 更新智能补货表中数据
                if (smartMap.containsKey(productId)){
                    smartMap.put(productId,Arith.add(smartMap.get(productId),purchaseProductEntity.getProductNum()));
                }else {
                    smartMap.put(productId,purchaseProductEntity.getProductNum());
                }
                // 封装采购结存需要的数据
                if(Objects.nonNull(contractProductId)){
                    contractProductIdList.add(contractProductId);
                    contractIdSet.add(contractId);
                    if (purchaseNumMap.containsKey(contractProductId)){
                        purchaseNumMap.put(contractProductId,Arith.add(productNum,purchaseNumMap.get(contractProductId)));
                    }else {
                        purchaseNumMap.put(contractProductId,productNum);
                    }
                    String onlyKey = contractProductId + "_" + productId;
                    if (balanceMap.containsKey(onlyKey)){
                        balanceMap.put(onlyKey,Arith.add(balanceMap.get(onlyKey),purchaseProductEntity.getProductNum()));
                    }else {
                        balanceMap.put(onlyKey,purchaseProductEntity.getProductNum());
                        onlyKeyList.add(onlyKey);
                    }
                }
            }
            if (CollectionsUtil.isNotEmpty(onlyKeyList)){
                List<PurchaseBalanceEntity> purchaseBalanceEntityList = purchaseBalanceModel.findByOnlyKeys(corpid, onlyKeyList);
                if (CollectionsUtil.isNotEmpty(purchaseBalanceEntityList)){
                    for (PurchaseBalanceEntity purchaseBalanceEntity : purchaseBalanceEntityList) {
                        String onlyKey = purchaseBalanceEntity.getOnlyKey();
                        if (balanceMap.containsKey(onlyKey)){
                            Double delNum = balanceMap.get(onlyKey);
                            Double balanceNum = purchaseBalanceEntity.getBalanceNum();
                            Double exceedStockNum = purchaseBalanceEntity.getExceedStockNum();
                            // 删除的总数量小于结存数量 则全部从结存中扣除 否则从库存中扣除
                            purchaseBalanceEntity.setBalanceNum(balanceNum >= delNum ? Arith.sub(balanceNum,delNum):0D);
                            purchaseBalanceEntity.setExceedStockNum(balanceNum >= delNum ? exceedStockNum : Arith.add(exceedStockNum,Arith.sub(delNum,balanceNum)));
                        }
                    }
                    try {
                        purchaseBalanceModel.updateBatch(purchaseBalanceEntityList, corpid);
                    }catch (Exception e){
                        LOG.error("PurchaseServiceImpl.deleteBatch() 更新以销定购表数据时出错", e);
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
                    }
                }

            }
        }
        // 查询出智能补货需要更新的数据
        List<SmartReplenishmentEntity> smartReplenishmentEntityList = smartReplenishmentModel.getByProductList(corpid,productIdList);
        if (CollectionsUtil.isNotEmpty(smartReplenishmentEntityList)){
            for (SmartReplenishmentEntity smartReplenishmentEntity : smartReplenishmentEntityList) {
                Long productId = smartReplenishmentEntity.getProductId();
                if (smartMap.containsKey(productId)){
                    Double pendingInstockNum = Objects.isNull(smartReplenishmentEntity.getPendingInstockNum()) ? 0D : smartReplenishmentEntity.getPendingInstockNum();
                    // 新的待入库数量 = 旧的待入库数量 - 本次删除掉的采购合同中的产品数量
                    smartReplenishmentEntity.setPendingInstockNum(Math.max(Arith.sub(pendingInstockNum, smartMap.get(productId)), 0D));
                }
            }
            try {
                smartReplenishmentModel.updateBatch(smartReplenishmentEntityList, corpid);
            }catch (Exception e){
                LOG.error("PurchaseServiceImpl.deleteBatch() 更新智能补货表数据时出错", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
        }
        // 处理合同产品表中缺货数量字段
        if(CollectionsUtil.isNotEmpty(contractProductIdList)){
            List<ContractProductEntity> byId = contractProductModel.getById(contractProductIdList, corpid);
            if (CollectionsUtil.isNotEmpty(byId)) {
                contractHelp.handleWaitPurchaseNum(corpid, byId, contractIdSet);
                try {
                    contractProductModel.updateBatch(byId, corpid);
                } catch (Exception e) {
                    LOG.error("PurchaseService.afterSave() 更新合同产品表中缺货数量数据时出错", e);
                }
            }
        }
    }
}
